初試啼聲,只用原生 JS 跟 CSS 寫「口罩地圖 」Ep.03


Posted by ABow_Chen on 2020-06-21

寫在前頭

保守估計再二至三篇,就可以結束這個系列文,六角學院的「JavaScript 作品實戰直播班」也開始了,身為學員的我,頓時又爆忙了起來,總之,文章能寫多少就盡力寫,但主線任務還是放在「JavaScript 作品實戰直播班」上囉!不過廢話不多說,今天的文章開始囉~

本篇記錄,會講到在左側 panel 裡的日期判斷及可購買日期的提醒

為地圖左側加入一個 panel

地圖的基本功能已完成,現在我們要來提升使用者體驗,要在地圖左側加入一個 panel 就是第一步,所以我們先在 HTML 建構出 panel 的區塊:

<div class="panel">
    // panel 的上半部
    <div class="panelTop">
    // info 區塊會用來判斷今天日期
        <div class="info">
            <div class="infoDate">
                <div class="todayDate"><h2>今天是&nbsp;<span></span></h2></div>
            </div>
            <div class="infoWeek">
                <h2>&nbsp;星期<span></span> </h2>
            </div>
        </div>
        // 此區塊則會告知購買資訊及下次可購買的日期
        <div class="idBuyText">
        <p class="idNumAll">身分證末碼數字&nbsp;<span>不限</span>&nbsp;皆可購買</p>
        </div>
        <div class="nextBuyDateText">
            <p class="nextBuyDate">今日購買,下次可購買日期為&nbsp;<span class="nextBuyDateNum"></span>&nbsp;星期<span class="nextBuyDay"></span></p>
        </div>
        // panel 裡有一個區塊是用來選擇縣市及鄉鎮的也先預留起來
        <div class="areaList">
            <select name="" id="" class="countyList">
            </select>
            <select name="" id="" class="townList">
            </select>
        </div>
    </div>
    // 這區塊是 panel 的下半部,這裡要塞進藥局的列表
    <div class="pharmacyList">
    </div>
</div>

接著我們要設定 CSS 的部分:

//定義出電腦版畫面裡 panel 的佔比,並讓 panel 固定在畫面的左邊,則帶有點陰影
.panel{
    width: 25%;
    height: 100%;
    position:absolute;
    top: 0;
    left:0;
    z-index: 99999;
    background-color:white;
    box-shadow: 2px 0px 3px 1px rgba(0, 0, 0, 0.25);
}

.panelTop{
    height: 50%;
    background-color:#63cf9c ;
    position: relative;
    display:flex;
    flex-direction: column;
    justify-content: center;
    margin-top:-2%;
    box-shadow: 0px 2px 3px 1px rgba(0, 0, 0, 0.3);
}

此時畫面呈現會如下:

在 panel 上半部塞進日期資訊

panel 的空間已經建構好了,接下來我們要在上半部塞進日期判斷的資訊,接下來是 JavaScript 的工作了。

function renderDate(){
    const dateInfo = new Date();
    const day = dateInfo.getDay();
    let date = dateInfo.getDate();
    let month = dateInfo.getMonth()+1;
    let year = dateInfo.getFullYear();
    const dayChinese = judgeChineseDay(day);
    const twoWeeks = 1000 * 60 * 60 * 24 * 14;
    const twoWeeksDate = new Date(new Date().getTime() + twoWeeks);
    let nextBuyTimeDate = twoWeeksDate.getDate();
    let nextBuyTimeMonth = twoWeeksDate.getMonth() + 1;
    let nextBuyTimeYear = twoWeeksDate.getFullYear();
    let today;
    let nextBuyDate;
    if(month.toString().length == 1){
        month = '0' + month;
        }
    if(date.toString().length == 1){
        date = '0' + date;
        }
    today = year + '-' + month + '-' + date;

    if (nextBuyTimeMonth.toString().length == 1) {
        nextBuyTimeMonth = '0' + nextBuyTimeMonth;
    }
    if (nextBuyTimeDate.toString().length == 1) {
        nextBuyTimeDate = '0' + nextBuyTimeDate;
    }
    nextBuyDate = nextBuyTimeYear + '-' + nextBuyTimeMonth + '-' + nextBuyTimeDate;
    if(day == 1 || day == 3 || day == 5){
        document.querySelector('.idNumAll').style.display = 'block';
    }else if(day == 2 || day == 4 || day == 6){
        document.querySelector('.idNumAll').style.display = 'block';
    }
    else if(day == 0){
        document.querySelector('.idNumAll').style.display = 'block';
    }else{
        alert('沒有這一天');
    }
        document.querySelector('.todayDate h2 span').textContent = today;
        document.querySelector('.infoWeek h2 span').textContent = dayChinese;
        document.querySelector('.nextBuyDate span').textContent = nextBuyDate;
        document.querySelector('.nextBuyDay').textContent = dayChinese;
    }

這裡有點長,我們分段來看:

// 先寫一個函式,把日期給渲染出來
function renderDate(){
    //這裡是取得日期的方法,MDN 上就有相關說明,附上網址在最下方資料參考處,若有需要可以參考
    const dateInfo = new Date();
    const day = dateInfo.getDay();
    let date = dateInfo.getDate();
    //因為月份是 0 到 11 所以我們要 +1
    let month = dateInfo.getMonth()+1;
    let year = dateInfo.getFullYear();
    // 下面這一段是我們要判斷星期的數字,並套進函式裡轉換成中文字
    const dayChinese = judgeChineseDay(day);
    // 這段是我們要計算出今日購買後,隔兩個禮拜後的可購買日,而以下的算式就是將毫秒計算成天數,總和就是 14 天
    const twoWeeks = 1000 * 60 * 60 * 24 * 14;
    // 然後把今天加了 14 天後的日期賦予到一個變數上
    const twoWeeksDate = new Date(new Date().getTime() + twoWeeks);
    let nextBuyTimeDate = twoWeeksDate.getDate();
    let nextBuyTimeMonth = twoWeeksDate.getMonth() + 1;
    let nextBuyTimeYear = twoWeeksDate.getFullYear();
    let today;
    let nextBuyDate;
}

接下來來看這一段:

// 把月份轉成字串,如果長度只有 1,那就在前面加上 0,針對 1 月至 9月
if(month.toString().length == 1){
    month = '0' + month;
    }
// 把日期轉成字串,如果長度只有 1,那就在前面加上 0,針對 1 日至 9日
if(date.toString().length == 1){
    date = '0' + date;
    }
//然後把今天的日期組出來    
today = year + '-' + month + '-' + date;
//用同樣的邏輯來判斷 14 天後的下次購買日的日期
if (nextBuyTimeMonth.toString().length == 1) {
    nextBuyTimeMonth = '0' + nextBuyTimeMonth;
}
if (nextBuyTimeDate.toString().length == 1) {
    nextBuyTimeDate = '0' + nextBuyTimeDate;
}
//然後把 14 天後的日期組出來    
nextBuyDate = nextBuyTimeYear + '-' + nextBuyTimeMonth + '-' + nextBuyTimeDate;

最後一段如下:

//此段的寫法原本是為了判斷星期幾對應身分證字號末碼而寫的,但後來規則改了,所以不管星期幾,顯示的資訊都是 .idNumAll 裡的「身分證末碼數字 不限 皆可購買」,所以這段僅供參考,純粹是規則改變,我以更動最少的方式為考量而寫的
if(day == 1 || day == 3 || day == 5){
    document.querySelector('.idNumAll').style.display = 'block';
}else if(day == 2 || day == 4 || day == 6){
    document.querySelector('.idNumAll').style.display = 'block';
}
// 這裡需要注意的是,星期日的 day 是 0,而不是 7
else if(day == 0){
    document.querySelector('.idNumAll').style.display = 'block';
}else{
    alert('沒有這一天');
}
    //最後在 HTML 相對應的標籤裡,把資訊渲染出來
    document.querySelector('.todayDate h2 span').textContent = today;
    document.querySelector('.infoWeek h2 span').textContent = dayChinese;
    document.querySelector('.nextBuyDate span').textContent = nextBuyDate;
    document.querySelector('.nextBuyDay').textContent = dayChinese;
}

加入 init() 裡

接著我們把 renderDate() 加入 init() 裡,讓網頁載入時預設執行。

// 原本只有 getData(),現在再加入 renderDate()
function init(){
    renderDate();
    getData();
}

將星期的數字轉換成中文字

我們習慣把星期寫成中文字,尤其星期日如果講成星期 7 會非常奇怪,所以我們就需要有個轉換的功能,因此我們寫了一個函式如下:

// 這個函式的功能很單純,就是把帶入的 day 從數字轉換成中文字
function judgeChineseDay(day){
    switch(day){
        case 1:
            return '一';
            break;
        case 2:
            return '二';
            break;
        case 3:
            return '三';
            break;
        case 4:
            return '四';
            break;
        case 5:
            return '五';
            break;
        case 6:
            return '六';
            break;
        case 0:
            return '日';
            break;
    }

}

以上這些部分完成後,我們就可以在 panel 看到今天的日期及 14 天後可購買的日期了!

資料補充


#口罩地圖 #六角學院 #台灣口罩地圖-2020 防疫要贏 #javascript #css #JavaScript 入門篇 - 學徒的試煉







Related Posts

Sorting Band Names without articles

Sorting Band Names without articles

字串小幫手 on linux

字串小幫手 on linux

Remove Duplicates from an Array (ES6)

Remove Duplicates from an Array (ES6)


Comments